/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package BaseDatos;

import BaseDatos.GeneradorMySQL.PrestamosMySQL;
import Controladores.GestorMensajes;
import Modelo.Prestamo;
import com.mysql.jdbc.Statement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import javax.swing.JOptionPane;

/**
 *
 * @author Marko
 */
public class GestorPrestamosBD{

////////////////////////////////////////////////////////////////////////////////
// Constructores
////////////////////////////////////////////////////////////////////////////////
    
    public GestorPrestamosBD(){
        iniciarComponentes();
    }
    
////////////////////////////////////////////////////////////////////////////////
// Interfaz de la clase
////////////////////////////////////////////////////////////////////////////////

    /**
     * busca el prestamo especificado
     * @param _numInventario
     * @return Devuelve el prestamo que coincida con la matricula ingresada
     */
    public Prestamo buscarPrestamo(String _numInventario){
        iniciarConexionBD();
        Prestamo prestamo = buscarPrestamoBD(_numInventario);
        return prestamo;
    }
    
    /**
     * administra la busqueda de todos los prestamos correspondientes al alumno
     * en la tabla de prestamos
     * @param _matriculaONombre
     * @return Devuelve la lista de prestamos activos del alumno o personal academico
     */
    public ArrayList<Prestamo> buscarPrestamos(String _matriculaONombre){
        iniciarConexionBD();
        ArrayList prestamosActivos = buscarPrestamosBD(_matriculaONombre);
        return prestamosActivos;                
    }
   
    /**
     * administra la cancelacion de los prestamos en la tabla de prestamos
     * @param _canceladoPor
     * @param _fechaCancelacion
     * @param _matricula
     * @param _numInventario 
     */
    public void cancelar(
     String _canceladoPor,
     Date _fechaCancelacion,
     String _matricula,
     String _numInventario
    ){
        iniciarConexionBD();
        String instruccionMySQLCancelacion = constructorInstruccionesMySQL.cancelacion(
                _canceladoPor, _fechaCancelacion, _matricula, _numInventario);
        String instruccionMySQLBorrado = constructorInstruccionesMySQL.borrado(_matricula, _numInventario);
        cancelarPrestamoBD(instruccionMySQLCancelacion, instruccionMySQLBorrado);        
    }
    
    /**
     * administra la devolucion de un prestamo
     * @param _matricula
     * @param _numInventario
     * @param _recibidaPor 
     * @param _fechaDevolucion 
     */
    public void devolucion(
     String _matricula, 
     String _numInventario, 
     String _recibidaPor,
     Date _fechaDevolucion) {
        iniciarConexionBD();
        String instruccionMySQLTraslado = constructorInstruccionesMySQL.devolucion(_matricula, 
                _numInventario, _recibidaPor, _fechaDevolucion);
        String instruccionMySQLBorrado = constructorInstruccionesMySQL.borrado(_matricula, _numInventario);
        devolucionPrestamo(instruccionMySQLTraslado, instruccionMySQLBorrado);
    }
    
    /**
     * modifica el prestamo en la base de datos
     * @param _prestamo
     */
    public void modificar(Prestamo _prestamo){
        iniciarConexionBD();
        modificarPrestamoBD(_prestamo);
    }
    
    /**
     * administra el registro de nuevos prestamos en la tabla de presamos
     * @param _nuevoPrestamo 
     */
    public void registrar(Prestamo _nuevoPrestamo) {
        iniciarConexionBD();
        registrarPrestamoBD(_nuevoPrestamo);
    }
    
    /**
     * Renueva un prestamo en la base de datos
     * @param _modificadoPor
     * @param _fechaDevolucion
     * @param _renovado
     * @param _numInventario 
     */
    public void renovacion(
     String _modificadoPor,
     Date _fechaDevolucion,
     int _renovado,
     String _numInventario
    ){
        iniciarConexionBD();
        renovarPrestamoBD(_modificadoPor, _fechaDevolucion, _renovado, _numInventario);
    }
    
////////////////////////////////////////////////////////////////////////////////
// Metodos Privados
////////////////////////////////////////////////////////////////////////////////
    
    /**
     * Ejecuta la instruccion para buscar el prestamo especifico solicitado
     * @param entrada_ResultadoBusqueda
     * @return Devuelve el prestamo solicitado en caso de no encontrar ninguna
     *          coincidencia devuelve null
     */
    private Prestamo buscarPrestamoBD(String _numInventario) {
        Prestamo prestamoActivo = null;
        try {
            ResultSet resultadoDeConsulta;
            String instruccionMySQL = constructorInstruccionesMySQL.consultaParticular(_numInventario);
            resultadoDeConsulta = adminSentenciasMySQL.executeQuery(instruccionMySQL);
            while(resultadoDeConsulta.next()){
                prestamoActivo = construirPrestamo(resultadoDeConsulta);
            }
        } catch (SQLException log) {
            GestorMensajes errorEncontrado = new GestorMensajes();
            errorEncontrado.mensajeError(log, _numInventario);
        } finally {
            terminarConexionBD();
        }
        
        return prestamoActivo;
    }
    
    /**
     * Ejecuta la instruccion para realizar la busqueda de los prestamos solicitados
     * @param _matriculaNombre
     * @return Devuelve la lista de prestamos activos
     */
    private ArrayList<Prestamo> buscarPrestamosBD(String _matriculaNombre){
        ArrayList<Prestamo> listaPrestamosActivos = new ArrayList<>();
        try {
            ResultSet resultadoDeConsulta;
            String instruccionMySQL = constructorInstruccionesMySQL.consultaGeneral(_matriculaNombre);
            resultadoDeConsulta = adminSentenciasMySQL.executeQuery(instruccionMySQL);
            while(resultadoDeConsulta.next()){
                Prestamo prestamoActivo  = construirPrestamo(resultadoDeConsulta);
                listaPrestamosActivos.add(prestamoActivo);
            }
        } catch (SQLException log) {
            GestorMensajes errorEncontrado = new GestorMensajes();
            errorEncontrado.mensajeError(log, _matriculaNombre);
        } finally {
            terminarConexionBD();
        }
        return listaPrestamosActivos;
    }
    
    /**
     * construye el prestamo basado en el resultado de la consulta que le pasen
     * @param _resultadoConsulta
     * @return Devuelve el prestamo
     */
    private Prestamo construirPrestamo(ResultSet _resultadoConsulta){
        Prestamo prestamoActivo = new Prestamo();
        try {
            
            /*String nombre = _resultadoConsulta.getString("Nombre");
            prestamoActivo.establecerNombre(nombre);
            
            String matricula = _resultadoConsulta.getString("Matricula");
            prestamoActivo.establecerMatricula(matricula);*/

            String numInventario = _resultadoConsulta.getString("NumInventario");
            prestamoActivo.establecerNumInventario(numInventario);
            
            String entregadaPor = _resultadoConsulta.getString("EntregadaPor");
            prestamoActivo.establecerEntregadoPor(entregadaPor);

            Date fechaEntrega = _resultadoConsulta.getTimestamp("FechaEntrega");
            prestamoActivo.establecerFechaEntrega(fechaEntrega);

            Date horaDevolucion = _resultadoConsulta.getTimestamp("FechaAproxDevolucion");
            prestamoActivo.establecerFechaLimite(horaDevolucion);

            String tipoPrestamo = _resultadoConsulta.getString("TipoPrestamo");
            prestamoActivo.establecerTipoPrestamo(tipoPrestamo);
            
        } catch (SQLException log) {
            prestamoActivo = null;
            GestorMensajes errorEncontrado = new GestorMensajes();
            errorEncontrado.mensajeError(log, " construirPrestamo, BD");
        }
        
        return prestamoActivo;
    }
    
    /**
     * Ejecuta las sentencias para la cancelacion el prestamo seleccionado
     * @param _instruccionMySQL 
     */
    private void cancelarPrestamoBD(
     String instruccionMySQLCancelacion,
     String instruccionMySQLBorrado
    ){
        try {
            adminSentenciasMySQL.executeUpdate(instruccionMySQLCancelacion);
            adminSentenciasMySQL.executeUpdate(instruccionMySQLBorrado);
            imprimirExitoSentenciaMySQL("Prestamo cancelado exitosamente");
        } catch (SQLException log) {
            GestorMensajes errorEncontrado = new GestorMensajes();
            errorEncontrado.mensajeError(log, " cancelarPrestamo, BD");
        } finally {
            terminarConexionBD();
        }
    }
    
    /**
     * Ejecuta las sentencias para la devolucion de un prestamo en la base de datos
     * @param _instruccionMySQLTraslado
     * @param _instruccionMySQLBorrado 
     */
    private void devolucionPrestamo(
     String _instruccionMySQLTraslado,
     String _instruccionMySQLBorrado
    ){
        try{
            adminSentenciasMySQL.executeUpdate(_instruccionMySQLTraslado);
            adminSentenciasMySQL.executeUpdate(_instruccionMySQLBorrado);
            imprimirExitoSentenciaMySQL("Devolucion registrada Exitosamente");
        } catch (SQLException log){
            GestorMensajes errorEncontrado = new GestorMensajes();
            errorEncontrado.mensajeError(log, " devolucionPrestamo, BD");
        } finally {
            terminarConexionBD();
        }
    }
    
    /**
     * Imprime si al ejecucion de la sentencia MySQL fue exitosa
     * @param entrada_Mensaje 
     */
    private void imprimirExitoSentenciaMySQL(String entrada_Mensaje){
        JOptionPane.showMessageDialog(null, entrada_Mensaje);
    }
    
    /**
     * inicializa los componentes y variables globales de la clase
     */
    private void iniciarComponentes(){
        adminSentenciasMySQL = null;
        constructorInstruccionesMySQL = new PrestamosMySQL();
    }

    /**
     * Inicia una conexion con la base de datos
     */
    private void iniciarConexionBD(){
        GestorConexionBD conexionBD;
        conexionBD = GestorConexionBD.obtenerPermisosAdministradorConexion();
        
        adminSentenciasMySQL = conexionBD.abrirConexionBD();
    }
    
    /**
     * Ejecuta la sentencia para modificar el prestamo seleccionado en la base de datos
     * @param _prestamo 
     */
    private void modificarPrestamoBD(Prestamo _prestamo){
        String instruccionMySQL = constructorInstruccionesMySQL.modificar(_prestamo);
        try {
            adminSentenciasMySQL.executeUpdate(instruccionMySQL);
            imprimirExitoSentenciaMySQL("Prestamo actualizado exitosamente");
        } catch (SQLException log) {
            GestorMensajes errorEncontrado = new GestorMensajes();
            String numInventario = _prestamo.obtenerNumInventario();
            errorEncontrado.mensajeError(log, numInventario);
        } finally {
            terminarConexionBD();
        }
    }
    
    /**
     * Ejecuta la sentencia para registrar el nuevo prestamo en la base de datos
     * @param _instruccionMySQL 
     */
    private void registrarPrestamoBD(Prestamo _prestamo) {
        String instruccionMySQL = constructorInstruccionesMySQL.registro(_prestamo);
        try {     
            adminSentenciasMySQL.executeUpdate(instruccionMySQL);
            imprimirExitoSentenciaMySQL("Prestamo registrado exitosamente");
        } catch (SQLException log) {
            GestorMensajes errorEncontrado = new GestorMensajes();
            String numInventario = _prestamo.obtenerNumInventario();
            errorEncontrado.mensajeError(log, numInventario);
        } finally {
            terminarConexionBD();
        }
    }

    /**
     * Ejecuta la sentencia para la renovacion de un prestamo
     * @param _modificadoPor
     * @param _fechaDevolucion
     * @param _renovado
     * @param _numInventario 
     */
    private void renovarPrestamoBD(
     String _modificadoPor,
     Date _fechaDevolucion,
     int _renovado,
     String _numInventario
    ){
        String instruccionMySQL = constructorInstruccionesMySQL.renovacion(_modificadoPor, _fechaDevolucion, 
                _renovado, _numInventario);
        try {     
            adminSentenciasMySQL.executeUpdate(instruccionMySQL);
            imprimirExitoSentenciaMySQL("Prestamo renovado exitosamente");
        } catch (SQLException log) {
            GestorMensajes errorEncontrado = new GestorMensajes();
            errorEncontrado.mensajeError(log, _numInventario);
        } finally {
            terminarConexionBD();
        }
    }
    
    /**
     * termina la conexion con la base de datos
     */
    private void terminarConexionBD(){
        GestorConexionBD conexionBD;
        conexionBD = GestorConexionBD.obtenerPermisosAdministradorConexion();
        conexionBD.cerrarConexionBD();
    }
    
////////////////////////////////////////////////////////////////////////////////
// Declaracion de Variables
////////////////////////////////////////////////////////////////////////////////
    
    private PrestamosMySQL constructorInstruccionesMySQL;
    private static Statement adminSentenciasMySQL;
}